package com.wsoft.im.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.service.CommonMemberService;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.core.vo.MemberVO;
import com.wsoft.im.entity.ImGroupMemberEntity;
import com.wsoft.im.manager.ImGroupManager;
import com.wsoft.im.manager.ImGroupMemberManager;
import com.wsoft.im.mapper.ImGroupMemberMapper;
import com.wsoft.im.query.group.member.ToggleLeaderQuery;
import com.wsoft.im.query.group.member.UpdateGroupMemberQuery;
import com.wsoft.im.query.group.member.UpdateMemberQuery;
import com.wsoft.im.service.IImGroupMemberService;
import com.wsoft.im.vo.GroupMemberVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Z001
 * @since 2025年01月14日 09:21:20
 */
@Service
public class ImGroupMemberServiceImpl extends ServiceImpl<ImGroupMemberMapper, ImGroupMemberEntity> implements IImGroupMemberService {

    @Resource
    private ImGroupMemberManager memberManager;
    @Resource
    private ImGroupManager groupManager;
    @Resource
    private CommonMemberService memberService;
    /**
     * 新增群成员
     * @param query
     * @return
     */
    @Override
    public boolean addMember(UpdateMemberQuery query) {
        return memberManager.addMember(query.getGroupId(), query.getMemberIdList());
    }

    /**
     * 移除群成员
     * @param query
     * @return
     */
    @Override
    public boolean removeMember(UpdateMemberQuery query) {
        //判断是否为群主,
        boolean groupLeader = isGroupLeader(query.getGroupId());
        if(!groupLeader){
            //只有群主能操作
            Asserts.fail("[im.group.operation.must.leader]");
        }
        //移除群成员不能包含自己
        removeNotOwner(query.getMemberIdList());

        return  memberManager.removeMember(query.getGroupId(),query.getMemberIdList());
    }

    /**
     * 群成员退群
     * @param query
     * @return
     */
    @Override
    public boolean quitGroup(UpdateGroupMemberQuery query) {
        boolean groupLeader = isGroupLeader(query.getGroupId());
        if(groupLeader){
            Asserts.fail("[im.group.not.hava.owner]");
        }
        return memberManager.removeMember(query.getGroupId(), Collections.singletonList(LoginUserUtil.getUserInfo().getLoginUserVO().getId()));
    }

    /**
     * 解散群
     * @param query
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean dissolveGroup(UpdateGroupMemberQuery query) {
        boolean groupLeader = isGroupLeader(query.getGroupId());
        if(!groupLeader){
            //只有群主能操作
            Asserts.fail("[im.group.operation.must.leader]");
        }
        groupManager.removeById(query.getGroupId());
        memberManager.removeAllMember(query.getGroupId());
        return true;
    }

    /**
     * 获取群组下成员
     * @param groupId
     * @return
     */
    @Override
    public List<GroupMemberVO> getGroupMember(Long groupId) {
        List<MemberVO> memberVoList = memberService.getMemberList();
        Map<Long, MemberVO> memberMap = memberVoList.stream().collect(Collectors.toMap(MemberVO::getId, Function.identity()));

        List<ImGroupMemberEntity> memberList = memberManager.getMemberList(groupId);
        List<GroupMemberVO> resultList = new ArrayList<>();
        for (ImGroupMemberEntity entity : memberList) {
            GroupMemberVO convert = Convert.convert(GroupMemberVO.class, entity);
            convert.setMemberName(memberMap.containsKey(entity.getMemberId())? memberMap.get(entity.getMemberId()).getName():"");
            convert.setPhoto(memberMap.containsKey(entity.getMemberId())? memberMap.get(entity.getMemberId()).getPhoto():"");
            resultList.add(convert);
        }
        return resultList;
    }

    @Override
    public ImGroupMemberEntity getInfo(Long groupId) {
        return memberManager.getByGroupId(groupId,null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean toggleLeader(ToggleLeaderQuery query) {
        boolean member = memberManager.isMember(query.getId(), query.getMemberId());
        if(!member){
            return false;
        }
        if(!isGroupLeader(query.getId())){
            Asserts.fail("[im.group.operation.must.leader]");
        }
        removeLeader(query.getId());
        addNewLeader(query.getId(),query.getMemberId());
        return true;
    }


    // ################################## 私有方法  ##################################


    /**
     * 判断 当前登录人 是否为群主
     *
     * @param groupId
     */
    public boolean isGroupLeader(Long groupId) {
        ImGroupMemberEntity leader = memberManager.getGroupLeader(groupId);
        return null != leader && leader.getMemberId().equals(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
    }

    /**
     * 移除群主
     * @param groupId
     * @return
     */
    public boolean removeLeader(Long groupId){
        ImGroupMemberEntity leader = memberManager.getGroupLeader(groupId);
        if(null != leader && leader.getMemberId().equals(LoginUserUtil.getUserInfo().getLoginUserVO().getId())){
            leader.setIsGroupLeader(0);
           return memberManager.updateById(leader);
        }
        return false;
    }

    /**
     * 新增群主
     * @param groupId
     * @param memberId
     * @return
     */
    public boolean addNewLeader(Long groupId,Long memberId){
        ImGroupMemberEntity memberEntity = memberManager.getByGroupId(groupId, memberId);
        if(null != memberEntity){
            memberEntity.setIsGroupLeader(1);
            return memberManager.updateById(memberEntity);
        }
        return false;
    }

    /**
     * 移除的成员 不能包含自己
     * @param memberIdList
     */
    public void removeNotOwner(List<Long> memberIdList){
        if(memberIdList.contains(LoginUserUtil.getUserInfo().getLoginUserVO().getId())){
            //移除群成员不能包含自己
            Asserts.fail("[im.group.not.hava.owner]");
        }
    }


}
